//类模板特化：1.全特化 2.偏特化

template <class T1, class T2>
class Test
{
public:
    Test()
    {
        cout << "T1 T2" << endl;
    }
private:
    T1 _a;
    T2 _b;
};

//1.全特化
template<>
class Test<double, int>
{
public:
    Test()
    {
        cout << "double int" << endl;
    }
    void print()
    {
        cout << "全特化" << endl;
    }
private:
    double _c;
    int _b;
};

//2.偏特化
//1.
template<class T2>
class Test<int, T2>
{
public:
    Test()
    {
        cout << "int T2" << endl;
    }
private:
    int _a;
    T2 _b;
};

//2.
template<class T1, class T2>
class Test<T1*, T2*>
{
public:
    Test()
    {
        _a = new T1(3.0);
        _b = new T2(8.0);
        if (nullptr == _a || nullptr == _b)
            perror("new");
        cout << "T1* T2*" << endl;
    }
    void printSum()
    {
        double sum = *_a + *_b;
        cout << "和是：" << (double)sum << endl;
        printf("%lf", sum);//必须使用C的格式化输出函数才可以打印小数点
    }
    ~Test()
    {
        if (_a)
            delete _a;
        if (_b)
            delete _b;
    }
private:
    T1* _a;
    T2* _b;
};

//函数模板
// 
// 
//非类型模板参数
template<typename T, int N>
auto func(T x)
{
    return N + x;
}
//1.全特化
template <typename T1, typename T2>
auto Sum(T1 x1, T2 x2)
{
    return x1 + x2;
}

template <>
auto Sum<int*, double*>(int* p1, double* p2)//T1是int* 类型的，T2是int*类型的
{
    return *p1 + *p2;
}
template <class T1, class T2>
bool judge(T1 x1, T2 x2)
{
    return x1 == x2;
}


//特化一个专门判断字符串是否相等的函数模板
template<>
bool judge<char*, char*>(char* str1, char* str2)
{
    return strcmp(str1, str2);//
}
int main()
{
    cout << judge(2, 1.5) << endl;//隐式实例化函数模板
    cout << judge<int, int>(7, 7.7) << endl;//显示实例化函数模板
    //如果要用该函数模板比较字符串的是否相同（此时比较的就是指针大小了），那就必须对其进行特化
    char str1[] = "abcd";
    char str2[] = "abcd";
    cout << judge(str1, str2) << endl;
    vector<int> v;
    cout << "v size is：" << sizeof(v) << endl;//答案是16
    return 0;
}



template <typename T = int>
class A
{
public:
	A()
	{
		x = T();
		y = T();
	}
	A(T _x,T _y)
		:x(_x)
		,y(_y)
	{}

	A<T> operator+(const A<T>& a) const
	{
		A<T> tmp;
		tmp.x = x + a.x;
		tmp.y = y + a.y;
		return tmp;
	}
private:
	T x;
	T y;
};

//模板全特化
template<typename T1,typename T2>
auto sum(const T1& x1, const T2& x2)
{
	return x1 + x2;
}

//全特化
template<>
auto sum<A<>, A<>>(const A<>& x1, const A<>& x2)
{
	A<> tmp = x1 + x2;
	return tmp;
}

int main()
{
	int arg = 1;
	int&& n = arg; //error.  move(arg)即可
	auto sp = make_shared<int>(arg);  //make_shared会返回一个shared_ptr对象
	auto sp2 = make_shared<A<>>(1, 3);
}



//返回一个字符串(仅包含大写字母)中出现最多的字母和这个字母出现的次数
//要求时间复杂度是O(n)
pair<char, int> findFrequentCh(const string& str)
{
    int arr[26] = { 0 };
    pair<char, int> res('\0', 0);
    for (int i = 0;i < str.length();++i)
    {
        arr[str[i] - 'A']++;
        if (res.second < arr[str[i]-'A'])
        {
            res.first = str[i];
            res.second = arr[str[i]-'A'];
        }
    }
    return res;
}